package cn.android.support.v7.lib.sin.crown.utils;

/**
 * Created by 彭治铭 on 2018/2/9.
 */

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cn.android.support.v7.lib.sin.crown.base.BaseApplication;
import cn.android.support.v7.lib.sin.crown.encryption.base64.Base64;

/**
 * 数据存储
 * <p>
 * UtilSharedPreferences preferencesUtil =
 * UtilSharedPreferences.getSharedPreferencesUtil("personal_information");//实例化
 * preferencesUtil.setString("uid", info.getUid());//数据存储
 * preferencesUtil.getString("uid", "uid")//获取数据，参数二是默认数据，当读取数据为空，则采用默认数据。
 * <p>
 * 使用 getSharedPreferencesUtilNews可以实时的实现跨进程共享数据。
 *
 * @author 彭治铭
 */
@SuppressLint("NewApi")
public class SharedPreferencesUtils {

    private static SharedPreferencesUtils sharedPreferencesUtil;
    private Context context = BaseApplication.getInstance();

    /**
     * @param name 保存文件名
     * @return
     */
    public static SharedPreferencesUtils getSharedPreferencesUtil(String name) {
        if (sharedPreferencesUtil == null) {
            sharedPreferencesUtil = new SharedPreferencesUtils(name);
            return sharedPreferencesUtil;
        } else {
            return sharedPreferencesUtil;
        }

    }

    /**
     * 每一次都是新new出来的。确保跨进程共享数据。
     *
     * @param name 保存文件名
     * @return
     */
    public static SharedPreferencesUtils getSharedPreferencesUtilNews(String name) {
        return new SharedPreferencesUtils(name);
    }

    private SharedPreferences preferences;
    private SharedPreferences.Editor editor;

    private SharedPreferencesUtils(String name) {
        super();
        // TODO Auto-generated constructor stub
        /**
         * 三个值： MODE_PRIVATE 可被其它的应用读写， MODE_READABLE 可被其它的应用读，但是不可写
         * MODE_WRITEABLE 可被其它的应用写，但是不可读
         * context.MODE_MULTI_PROCESS跨进程分享数据
         */
        preferences = context.getSharedPreferences(name, context.MODE_PRIVATE | context.MODE_MULTI_PROCESS);
        editor = preferences.edit();
    }

    /**
     * 设置字符串
     *
     * @param key   关键字
     * @param value 值
     */
    public void setString(String key, String value) {
        editor.putString(key, value);
        editor.commit();
    }

    /**
     * 设置整数
     *
     * @param key   关键字
     * @param value 值
     */
    public void setInt(String key, int value) {
        editor.putInt(key, value);
        editor.commit();
    }

    /**
     * 设置布尔型
     *
     * @param key   关键字
     * @param value 值
     */
    public void setBoolean(String key, Boolean value) {
        editor.putBoolean(key, value);
        editor.commit();
    }

    /**
     * 设置浮点型
     *
     * @param key   关键字
     * @param value 值
     */
    public void setFloat(String key, Float value) {
        editor.putFloat(key, value);
        editor.commit();

    }

    /**
     * 设置长整形
     *
     * @param key   关键字
     * @param value 值
     */
    public void setLong(String key, Long value) {
        editor.putLong(key, value);
        editor.commit();
    }

    /**
     * @param key   关键字
     * @param value 值
     */
    public void setList(String key, List<String> value) {
        /**
         * 转换当中可能要丢失数据,尤其是从list转换到set的时候, 因为set不能有重复数据 //还有转换到set之后,
         * 他们原先在list上的顺序就没了,
         */
        Set<String> set = new HashSet<String>();
        set.addAll(value);// 给set填充

        editor.putStringSet(key, set);
        editor.commit();
    }

    /**
     * 获取List集合
     *
     * @param key 关键字
     * @return
     */
    public List<String> getList(String key) {

        Set<String> set = preferences.getStringSet(key, null);
        List<String> list = new ArrayList<String>();
        list.clear();// 清空list，不然下次把set元素加入此list的时候是在原来的基础上追加元素的
        if (set != null) {
            list.addAll(set);// 把set的
        }
        return list;
    }

    /**
     * 获取字符串
     *
     * @param key      关键字
     * @param defValue 默认值
     */
    public String getString(String key, String defValue) {
        return preferences.getString(key, defValue);
    }

    /**
     * 获取整数
     *
     * @param key      关键字
     * @param defValue 默认值
     */
    public int getInt(String key, int defValue) {
        return preferences.getInt(key, defValue);
    }

    /**
     * 获取布尔型
     *
     * @param key      关键字
     * @param defValue 默认值
     */
    public Boolean getBoolean(String key, Boolean defValue) {
        return preferences.getBoolean(key, defValue);

    }

    /**
     * 获取浮点型
     *
     * @param key      关键字
     * @param defValue 默认值
     */
    public float getFloat(String key, Float defValue) {
        return preferences.getFloat(key, defValue);

    }

    /**
     * 获取长整形
     *
     * @param key      关键字
     * @param defValue 默认值
     */
    public Long getLong(String key, Long defValue) {
        return preferences.getLong(key, defValue);
    }

    //其中Base64在org.apache.http.legacy.jar里面，该包也解决了网络无法使用的问题。

    /**
     * 保存Objiect对象(亲测可行)
     * 对象必须具备空构造函数，已经getter和setter方法。已及继承Serializable(序列化)
     *
     * @param key
     * @param obj
     */
    public void saveObject(String key, Object obj) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            //Base64.encodeBase64需要org.apache.http.legacy.jar包
            //String personBase64 = new String(Base64.encodeBase64(baos.toByteArray()));
            String personBase64 = new String(Base64.encode(baos.toByteArray()));
            editor.putString(key, personBase64);
            editor.commit();
            oos.close();
            baos.close();
        } catch (Exception e) {
            Log.e("test", "对象保存失败" + e.getMessage());
        }
    }

    /**
     * 获取Object对象，空返回null
     *
     * @param key
     * @return
     */
    public Object getObjectInfo(String key) {
        Object obj = null;
        try {
            String personBase64 = preferences.getString(key, "");
            if (personBase64.equals("")) {
                Log.e("test", "对象为空");
                return obj;
            }
            //这个Base64.decodeBase64需要org.apache.http.legacy.jar包
            //byte[] base64Bytes = Base64.decodeBase64(personBase64.getBytes());
            byte[] base64Bytes = Base64.decode(personBase64);
            ByteArrayInputStream bais = new ByteArrayInputStream(base64Bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            obj = ois.readObject();
            ois.close();
        } catch (Exception e) {
            Log.e("test", "读取失败:\t" + e.getMessage());
        }
        return obj;
    }


}
